package com.zs.grain.ui

import android.app.Application
import android.app.PendingIntent
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbManager
import android.media.AudioManager
import android.util.Base64
import android.util.Log
import android.widget.Toast
import androidx.lifecycle.MutableLiveData
import com.github.mjdev.libaums.UsbMassStorageDevice
import com.github.mjdev.libaums.fs.FileSystem
import com.github.mjdev.libaums.fs.UsbFile
import com.github.mjdev.libaums.fs.UsbFileStreamFactory
import com.jeremyliao.liveeventbus.LiveEventBus
import com.tencent.bugly.beta.Beta
import com.xnkj1688.semplibrary.mvvm.*
import com.zs.grain.service.*
import com.xnkj1688.semplibrary.entity.Advertisement
import com.zs.grain.device.EnumLightStatus
import com.zslibrary.BusMaster.BusMaster
import io.reactivex.Completable
import io.reactivex.Observable
import io.reactivex.schedulers.Schedulers
import io.reactivex.subjects.SingleSubject
import java.io.File
import java.io.FileOutputStream
import java.lang.Exception
import java.sql.Date
import java.util.*
import javax.inject.Inject
import kotlin.concurrent.schedule
import io.reactivex.Single

/**
 * Created by Wesley on 2017/7/17.
 */

class SettingViewModel @Inject constructor(
    val mApp: Application,
    val mDataService: DataService,
    val mSignalRService: SignalRService,
    val mDeviceService: DeviceService,
    val mSoundService:SoundService,
    val mTimerService:TimerService,
    val mContext: Context
) : BaseViewModel(mApp) {
    val currentCraft = MutableLiveData<String>()
    val terminalId = MutableLiveData<String>()
    val verifyCode = MutableLiveData<String>()
    val server = MutableLiveData<String>()
    val currentVol = MutableLiveData<String>()
    val currentVol2 = MutableLiveData<String>()
    val advertisements = MutableLiveData<MutableList<Advertisement>>()
    val syncTime: String?
        get() = mDataService.getSetting("SyncTime")
    val hardwareVersion
        get() = mDeviceService.hardwareVersion

    val ioAppVersion
        get() = mDeviceService.ioAppVersion
    val ioBootVersion
        get() = mDeviceService.ioBootVersion
    val cupAppVersion
        get() = mDeviceService.cupAppVersion
    val cupBootVersion
        get() = mDeviceService.cupBootVersion
    val craftVersion
        get() = mDeviceService.craftVersion

    val isUVLightEnable:Boolean
        get() = mDataService.isLocalDBEnabld("uvlight")

    val uvLightLTime:String?
        get() {
            var text = mDataService.getFromLocalDatabase("uvlight","setting")
            //if(text!=null) text=text.substring(7)
            return text
        }

    val isAREnable:Boolean
        get() = mDataService.isLocalDBEnabld("reboot")

    val isVolEnable:Boolean
        get() = mDataService.isLocalDBEnabld("vol")

    val isVol1Enable:Boolean
        get() = mDataService.isLocalDBEnabld("vol1")

    val isVol2Enable:Boolean
        get() = mDataService.isLocalDBEnabld("vol2")

    val restartTime:String?
        get() {
            var text = mDataService.getFromLocalDatabase("reboot","time")
            if(text == null) text = "设定时间"
            return text
        }

    val uvLightSettingTime:String?
        get() {
            var text = mDataService.getFromLocalDatabase("uvlight","time")
            if(text == null) text = "开启时间"
            return text
        }

    val volTime1:String?
        get() {
            var text = mDataService.getFromLocalDatabase("vol1","time")
            if(text == null) text = "设定1"
            return text
        }

    val volTime2:String?
        get() {
            var text = mDataService.getFromLocalDatabase("vol2","time")
            if(text == null) text = "设定2"
            return text
        }

    val appVersion: String
        get() {
            val info = mApp.packageManager.getPackageInfo(mApp.packageName, 0)
            return info.versionName + "." + info.versionCode
        }

    private var mProgressTimer: Timer? = null
    //var autoRT:Date? = null

    init {
        terminalId.value = mDataService.terminalId.toString()
        verifyCode.value = mDataService.verifyCode
        server.value = mDataService.server
        advertisements.value = mDataService.playingAdsList()//advertisements
        currentCraft.value = getCraftName(mDataService.craftPath)
        //autoRT = mDataService.autoRebootTime
        val am = mContext.getSystemService(Context.AUDIO_SERVICE) as AudioManager
        currentVol.value = ((am.getStreamVolume(AudioManager.STREAM_MUSIC))*6).toString()
        currentVol2.value = ((am.getStreamVolume(AudioManager.STREAM_NOTIFICATION))*12).toString()
    }

    fun getCraftName(filePath:String):String{
        val fileNames: MutableList<String> = mutableListOf()
        //在该目录下走一圈，得到文件目录树结构
        val fileTree: FileTreeWalk = File(filePath).walk()
        fileTree.maxDepth(1) //需遍历的目录层次为1，即无须检查子目录
            .filter { it.isFile } //只挑选文件，不处理文件夹
//        .filter { it.extension == "txt"  } //选择扩展名为txt的文本文件
            .filter { it.extension in listOf("json") }//选择扩展名为txt或者mp4的文件
            .filter { it.name.contains("zsRcp") }
            .forEach { fileNames.add(it.name) }//循环 处理符合条件的文件
        //deleteIfNoUnique(filePath,"LocalAdjustments.json")

        if(!fileNames.isEmpty())
            return fileNames.find {  x -> x.contains("zsRcp") }!!
        else return "---无---"
        //(fileNames.find {  x -> x.contains("zsRcp") }!!)?:"---无---"
    }

    fun startAdjustVolumn(streamType:Int){
        mSoundService.playSound(streamType,SoundService.EnumSound.DINGDONG)
    }

    fun changeVolText(streamType:Int,progress:Int){
        var result = progress
        if(streamType==3) {
            if (progress <= 6) result = 6
            currentVol.postValue(result.toString())
        }else{
            if (progress <= 12) result = 12
            currentVol2.postValue(result.toString())
        }
    }

    fun getSettingFromCloud(mcb:Boolean,pcb:Boolean,scb:Boolean) {
        if(scb){
            mSignalRService.settings
                .map {
                    var server = mDataService.server;

                    mDataService.DaoSetting.deleteAll();
                    mDataService.DaoSetting.insertInTx(it.toList());
                    if (server != mDataService.server)
                        mSignalRService.init("http://" + mDataService.server)
                    this.terminalId.postValue(mDataService.terminalId.toString())
                    this.verifyCode.postValue(mDataService.verifyCode)
                    this.server.postValue(mDataService.server)

                    mDeviceService.init();
                    it.size
                }
                .map {
                    //uiNotify.postValue(super.getToastNotify("终端配置同步成功(${it}条)", Toast.LENGTH_SHORT))
                    mDataService.insertLog("Operation:终端配置同步成功(${it}条)")
                }
                .flatMap {
                    mSignalRService.advertisements
                }.map {
                    mDataService.DaoAdvertisement.deleteAll()
                    mDataService.DaoAdvertisement.insertInTx(it.toList())
                    it.size
                }.map {
                    //uiNotify.postValue(super.getToastNotify("广告数据同步成功(${it}条)", Toast.LENGTH_SHORT))
                    mDataService.insertLog("Operation:广告数据同步成功(${it}条)")
                }.subscribe({
                    postToast("系统数据同步成功", Toast.LENGTH_SHORT)
                    mDataService.insertLog("Operation:系统数据同步成功")
                }, {
                    postToast("系统数据同步失败", Toast.LENGTH_SHORT)
                    mDataService.insertLog("Operation:系统数据同步失败")
                })
        }

        if(pcb){
            mSignalRService.settings
                .flatMap {
                    mSignalRService.menus
                }.map {
                    mDataService.DaoMenu.deleteAll()
                    mDataService.DaoMenu.insertInTx(it.toList())
                    it.size
                }.map {
                    //uiNotify.postValue(super.getToastNotify("菜单数据同步成功(${it}条)", Toast.LENGTH_SHORT))
                    mDataService.insertLog("Operation:菜单数据同步成功(${it}条)")
                }.flatMap {
                    mSignalRService.categories
                }.map {
                    mDataService.DaoCategory.deleteAll()
                    mDataService.DaoCategory.insertInTx(it.toList())
                    it.size
                }.map {
                    //uiNotify.postValue(super.getToastNotify("分类数据同步成功(${it}条)", Toast.LENGTH_SHORT))
                    mDataService.insertLog("Operation:分类数据同步成功(${it}条)")
                }.flatMap {
                    mSignalRService.goods
                }.map {
                    mDataService.DaoGood.deleteAll()
                    mDataService.DaoGood.insertInTx(it.toList())
                    it.size
                }.map {
                    //uiNotify.postValue(super.getToastNotify("商品数据同步成功(${it}条)", Toast.LENGTH_SHORT))
                    mDataService.insertLog("Operation:商品数据同步成功(${it}条)")
                }.flatMap {
                    mSignalRService.ingridents
                }.map {
                    mDataService.DaoIngrident.deleteAll()
                    mDataService.DaoIngrident.insertInTx(it.toList())
                    it.size
                }.map {
                    //uiNotify.postValue(super.getToastNotify("原料数据同步成功(${it}条)", Toast.LENGTH_SHORT))
                    mDataService.insertLog("Operation:商品数据同步成功(${it}条)")
                }
                .flatMap {
                    mSignalRService.receipes
                }.map {
                    mDataService.DaoReceipe.deleteAll()
                    mDataService.DaoReceipe.insertInTx(it.toList())
                    it.size
                }.map {
                    //uiNotify.postValue(super.getToastNotify("配方数据同步成功(${it}条)", Toast.LENGTH_SHORT))
                    mDataService.insertLog("Operation:配方数据同步成功(${it}条)")
                }
                .flatMap {
                    mSignalRService.images
                }.map {
                    mDataService.DaoImage.deleteAll()
                    mDataService.DaoImage.insertInTx(it.toList())
                    it
                }.map {
                    //uiNotify.postValue(getToastNotify("图片数据同步成功(${it.size})条)", Toast.LENGTH_SHORT))//size
                    mDataService.insertLog("Operation:图片数据同步成功(${it.size})条)")//
                    it
                }.toObservable()
                .flatMap {
                    var dir = File(mDataService.imagesPath)
                    if (!dir.exists()) dir.mkdir()
                    Observable.fromIterable(it.toList())
                }.observeOn(Schedulers.newThread())
                .map {
                    val fileName = "${mDataService.imagesPath}/${it.getFileName()}"
                    var file = File(fileName)
                    if ((file.exists() && it.remark == null) || (it.remark != null && file.lastModified() >= Date.valueOf(
                            it.remark
                        ).getTime())
                    )
                        return@map

                    var single = mSignalRService.getImage(it.id)
                    single.map {
                        var data = Base64.decode(it, Base64.NO_WRAP);
                        var fos = FileOutputStream(file);
                        fos.write(data);
                        fos.close();
                    }.subscribe({
                        //uiNotify.postValue(getToastNotify("图片下载成功:\n${file.name}", Toast.LENGTH_SHORT))
                        mDataService.insertLog("Operation:图片下载成功:${file.name}")
                    }, {
                        postToast("图片下载失败:\n${file.name}", Toast.LENGTH_LONG)
                        mDataService.insertLog("Operation:图片下载失败:${file.name}")
                    })
                    Completable.fromSingle(single).blockingGet()
                }
                .subscribe({
                }, {
                    postToast("产品数据同步失败", Toast.LENGTH_SHORT)
                    mDataService.insertLog("Operation:产品数据同步失败")
                }, {
                    postToast("产品数据同步成功", Toast.LENGTH_SHORT)
                    mDataService.insertLog("Operation:产品数据同步成功")
                })
        }

        if(mcb){
            mSignalRService.settings
                .flatMap {
                    mSignalRService.components
                }.map {
                    if(it.size<=0){
                        var components = mDeviceService.components
                        mDataService.update(components)
                        LiveEventBus.get("SyncService.UploadComponents").post(0)
                    } else {
                        mDataService.DaoComponent.deleteAll()
                        mDataService.DaoComponent.insertInTx(it.toList())
                    }
                    it.size
                }.map {
                    postToast("部件数据同步成功(${it}条)", Toast.LENGTH_SHORT)
                    mDataService.insertLog("Operation:部件数据同步成功(${it}条)")
                }.flatMap {
                    mSignalRService.adjustments
                }.map {
                    mDataService.DaoAdjustment.deleteAll()
                    mDataService.DaoAdjustment.insertInTx(it.toList())
                    mDeviceService.setAdjustments()
                    it.size
                }.map {
                    //uiNotify.postValue(super.getToastNotify("部件参数同步成功(${it}条)", Toast.LENGTH_SHORT))
                    mDataService.insertLog("Operation:部件参数同步成功(${it}条)")
                }
                .subscribe({
                    postToast("机器数据同步成功", Toast.LENGTH_LONG)
                    mDataService.insertLog("Operation:机器数据同步成功")
                }, {
                    postToast("机器数据同步失败", Toast.LENGTH_SHORT)
                    mDataService.insertLog("Operation:机器数据同步失败")
                })
        }

    }

    fun onUpgradeIoApp() {
        mDataService.insertLog("Operation:IoApp升级")
        this.upgrade("IoApp", ioAppVersion)
    }

    fun onUpgradeIoBoot() {
        mDataService.insertLog("Operation:IoBoot升级")
        this.upgrade("IoBoot", ioBootVersion)
    }

    fun onUpgradeCupApp() {
        mDataService.insertLog("Operation:CupApp升级")
        this.upgrade("CupApp", cupAppVersion)
    }

    fun onUpgradeCupBoot() {
        mDataService.insertLog("Operation:CupBoot升级")
        this.upgrade("CupBoot", cupBootVersion)
    }

    fun onUpgradeApp() {
        mDataService.insertLog("Operation:应用升级")
        Beta.checkUpgrade()
    }

    fun onUpgradeCraft() {
        mDataService.insertLog("Operation:下载工艺")
        this.upgrade("Craft", craftVersion)
    }

    private fun upgrade(type: String, version: String) {
        //mDataService.insertLog("${type}:${version}升级")
        when (type) {
            "Craft" -> this.uiNotify.postValue(this.getNotify("CraftDownload"))
            else -> this.uiNotify.postValue(this.getNotify("SoftUpdate"))
        }
        //this.uiNotify.postValue(this.getNotify("ShowProgress"))
        startProgressTimer()
        this.getUpgradeFile(type, version)
            .subscribe({
                if (it == null || it == "") {
                    postToast("无可以升级版本", Toast.LENGTH_LONG)
                    this.stopProgressTimer()
                    return@subscribe
                }
                when (type) {
                    "IoBoot" -> mDeviceService.updateIoBoot(it)
                    "IoApp" -> mDeviceService.updateIoApp(it)
                    "CupBoot" -> mDeviceService.updateCupBoot(it)
                    "CupApp" -> mDeviceService.updateCupApp(it)
                    "Craft" -> {
                        mDataService.insertLog("State:开始显示工艺下载结果")
                        postToast("工艺下载完成,5秒后机器将自动重启...", Toast.LENGTH_LONG)
                        mDataService.insertLog("State:准备重启")
                        this.stopProgressTimer()
                        Thread.sleep(5 * 1000);
                        BusMaster.getInstance(mContext).resetBoard()
                        val componetName = ComponentName(
                            "com.example.reboottest",
                            "com.example.reboottest.MainActivity"
                        );
                        val intent = Intent();
                        intent.setComponent(componetName);
                        mApp.startActivity(intent);
                    }
                }
                this.stopProgressTimer()
            }, {
                it.printStackTrace()
                postToast("升级异常：" + (it.message ?: ""), Toast.LENGTH_LONG)
                Thread.sleep(1000)
                this.stopProgressTimer()
            })
    }

    private fun getUpgradeFile(type: String, version: String): Single<String> {
       // mDataService.insertLog("State:开始下载工艺")
        var result = SingleSubject.create<String>()
        mSignalRService.checkUpdate(type, version)
            .subscribe({
                if (it.first <= 0) result.onSuccess("")
                var id = it.first
                var fileName = it.second
                var dir = File(mDataService.craftPath)
                if (!dir.exists()) dir.mkdir()
                fileName = "${mDataService.craftPath}/${fileName}"
                val file = File(fileName)
                if (file.exists()) file.delete()

                mSignalRService.downloadResource(id.toLong())
                    .subscribe({
          //              mDataService.insertLog("State:写入工艺文件")
                        if(fileName.contains("zsRcp"))
                            deleteIfNoUnique(mDataService.craftPath,fileName)

                        var data = Base64.decode(it, Base64.NO_WRAP);
                        var fos = FileOutputStream(fileName);
                        fos.write(data);
                        fos.flush();
                        fos.close();
            //            mDataService.insertLog("State:工艺文件操作流关闭")
                        result.onSuccess(fileName)
              //          mDataService.insertLog("State:工艺下载成功")
                        return@subscribe
                    }, {
                        //mDataService.insertLog("State:工艺文件下载异常")
                        result.onError(Exception("资源下载失败:\n${file.name}\n"))
                    })
            }, {
                //mDataService.insertLog("State:工艺下载失败")
                it.printStackTrace()
                result.onError(it)
            })
        return result
    }

    fun deleteIfNoUnique(filePath:String,fileName:String){
        //val fileNames: MutableList<String> = mutableListOf()
        //在该目录下走一圈，得到文件目录树结构
        val fileTree: FileTreeWalk = File(filePath).walk()
        fileTree.maxDepth(1) //需遍历的目录层次为1，即无须检查子目录
            .filter { it.isFile } //只挑选文件，不处理文件夹
//        .filter { it.extension == "txt"  } //选择扩展名为txt的文本文件
            .filter{it.name.contains("zsRcp")}
            .filter { it.name != filePath+"/"+fileName}
            .forEach { it.delete() }
        //if((fileNames.find {  x -> x.contains("zsRcp") }!!)!=fileName)
    }

    fun startProgressTimer() {
        this.mProgressTimer = Timer()
        this.mProgressTimer?.schedule(1000, 1000) {
            var producingProgress = mDeviceService.updateProgress
            if (producingProgress >= 100)
                stopProgressTimer()
        }
    }

    fun stopProgressTimer() {
        this.uiNotify.postValue(this.getNotify("HideProgress"))
        this.mProgressTimer?.cancel()
        this.mProgressTimer = null
    }

    fun onClickRead() {
        mDataService.insertLog("Operation:更新广告列表")
        Single.just("")
            .observeOn(Schedulers.io())
            .subscribe({
                val result = this.readUsb("/zs_assets/ads/", mDataService.adsPath)
                if (result == null) return@subscribe

                val ads = mDataService.advertisements
                var adsPath = mDataService.adsPath
                val list = ArrayList<Advertisement>()
                for (item in result) {
                    item.fileName = item.fileName.replace(adsPath, "")
                    var ad = ads.find { x -> x.fileName == item.fileName }
                    if (ad == null) {
                        mDataService.DaoAdvertisement.insert(item)
                        //advertisementViewModels2.postValue(item)
                    } else if (ad.delete ?: false) {
                        File("$adsPath${item.fileName}").delete()
                        mDataService.DaoAdvertisement.delete(ad)
                    }
                }
                for (item in ads) {
                    var ad = result.find { x -> x.fileName == item.fileName }
                    if (ad == null && (item.enable ?: false))
                        mDataService.DaoAdvertisement.delete(item)
                }
                var advertisements = mDataService.advertisements.toTypedArray()
                if (advertisements != null && advertisements.size > 0) {
                    mSignalRService.uploadAdvertisements(advertisements)
                        .flatMap {
                            if (it) mSignalRService.advertisements
                            else {
                                this.uiNotify.postValue(this.getNotify("HideProgress"))
                                throw Exception("广告列表上传云端失败")
                            }
                        }.subscribe({
                            mDataService.DaoAdvertisement.deleteAll()
                            mDataService.DaoAdvertisement.insertInTx(it.toList())
                            postToast("广告列表上传云端成功", Toast.LENGTH_SHORT)
                            Thread.sleep(1000)
                            this.uiNotify.postValue(this.getNotify("HideProgress"))
                            updateVideoList()
                        }, {
                            it.printStackTrace()
                            postToast("广告列表同步失败：" + it.message, Toast.LENGTH_LONG)
                            Thread.sleep(1000)
                            this.uiNotify.postValue(this.getNotify("HideProgress"))
                        })
                } else
                    this.uiNotify.postValue(this.getNotify("HideProgress"))
            }, {
                it.printStackTrace()
                postToast("广告更新失败:" + it.message, Toast.LENGTH_LONG)
                Thread.sleep(1000)
                this.uiNotify.postValue(this.getNotify("HideProgress"))
            })

    }

    fun updateVideoList() {

    }

    fun onLightModel1(){
        mDeviceService.mMcuDevice.mcuLightControl(EnumLightStatus.NORMAL)
    }

    fun onLightModel2(){
        mDeviceService.mMcuDevice.mcuLightControl(EnumLightStatus.INIT)
    }

    fun onLightModel3(){
        mDeviceService.mMcuDevice.mcuLightControl(EnumLightStatus.WARNING)
    }

    fun onLightModel4(){
        mDeviceService.mMcuDevice.mcuLightControl(EnumLightStatus.TEST2)
    }

    fun onLightModel5(){
        mDeviceService.mMcuDevice.mcuLightControl(EnumLightStatus.TEST3)
    }

    fun onVoiceAutoTimer(){
        //mTimerService.addAlarm2()
    }

    fun onVoiceAutoTimer2(){
        //mTimerService.addAlarm2()
    }

    fun onVoiceIncrease(streamType:Int){
        val am = mContext.getSystemService(Context.AUDIO_SERVICE) as AudioManager
        var volumnCurrent = "-1"
        if(streamType==3){
            var tmp = am.getStreamVolume(streamType)
            if(tmp<12) {
                volumnCurrent = ((am.getStreamVolume(streamType) + 1) * 6).toString()
                currentVol.postValue(volumnCurrent)
                mSoundService.soundAdd(1, streamType)
                mSoundService.playSound(streamType, SoundService.EnumSound.DINGDONG)
            }
        }else{
            if(am.getStreamVolume(AudioManager.STREAM_NOTIFICATION)==0)
                postToast("请关闭勿扰模式", Toast.LENGTH_SHORT)
            else {

                if(am.getStreamVolume(streamType)<7) {
                    volumnCurrent = ((am.getStreamVolume(streamType) + 1) * 12).toString()
                    currentVol2.postValue(volumnCurrent)
                    mSoundService.soundAdd(1, streamType)
                    //if(am.getStreamVolume(streamType)<7)
                    mSoundService.playSound(streamType, SoundService.EnumSound.DINGDONG)
                }
            }
        }
    }

    fun onVoiceReduce(streamType:Int){
        var am = mContext.getSystemService(Context.AUDIO_SERVICE) as AudioManager
        var volumnCurrent = "-1"
        if(streamType==3){
            var tmp = am.getStreamVolume(streamType)
            if(tmp>1) {
                volumnCurrent = ((am.getStreamVolume(streamType) - 1) * 6).toString()
                currentVol.postValue(volumnCurrent)
                mSoundService.soundDel(1, streamType)
                mSoundService.playSound(streamType, SoundService.EnumSound.DINGDONG)
            }
        }else{
            if(am.getStreamVolume(AudioManager.STREAM_NOTIFICATION)==0)
                postToast("请关闭勿扰模式", Toast.LENGTH_SHORT)
            else {
                //var tmp = am.getStreamVolume(streamType)
                if(am.getStreamVolume(streamType)>1) {
                    volumnCurrent = ((am.getStreamVolume(streamType) - 1) * 12).toString()
                    currentVol2.postValue(volumnCurrent)
                    mSoundService.soundDel(1, streamType)
                    mSoundService.playSound(streamType, SoundService.EnumSound.DINGDONG)
                }
            }
        }
    }

    fun onUsbAttached(context: Context, intent: Intent) {
        intent.getParcelableExtra<UsbDevice>(UsbManager.EXTRA_DEVICE)?.run {
            val usbManager = context.getSystemService(Context.USB_SERVICE) as UsbManager
            var storageDevices = UsbMassStorageDevice.getMassStorageDevices(context)
            for (device in storageDevices) {
                if (device.usbDevice.deviceId == this.deviceId) {
                    if (!usbManager.hasPermission(device.usbDevice)) {
                        Log.d(AdvertisementViewModel.TAG, "requestPermission")
                        val pendingIntent = PendingIntent.getBroadcast(
                            context, 0,
                            Intent(AdvertisementViewModel.ACTION_USB_PERMISSION), 0
                        )
                        usbManager.requestPermission(device.getUsbDevice(), pendingIntent)
                    }
                    break
                }
            }
        }
    }

    fun onUsbPermession(context: Context, intent: Intent) {
        intent.getParcelableExtra<UsbDevice>(UsbManager.EXTRA_DEVICE)?.run {
            //            val path = intent.getStringExtra("Path")
            val usbManager = context.getSystemService(Context.USB_SERVICE) as UsbManager
            var storageDevices = UsbMassStorageDevice.getMassStorageDevices(context)
            for (device in storageDevices) {
                if (device.usbDevice.deviceId == this.deviceId) {
                    if (usbManager.hasPermission(device.usbDevice)) {
//                        readDevice(device, "zs_assets")
                    }
                    break
                }
            }
        }
    }

    fun readUsb(srcPath: String, dstPath: String): MutableList<Advertisement>? {
        var result = ArrayList<Advertisement>()
        var storageDevices = UsbMassStorageDevice.getMassStorageDevices(mApp)
        val usbManager = mApp.getSystemService(Context.USB_SERVICE) as UsbManager
        for (device in storageDevices) {
            if (usbManager.hasPermission(device.usbDevice)) {
                var list = readDevice(device, srcPath, dstPath)
                result.addAll(list)
            } else {
                val intent = Intent(AdvertisementViewModel.ACTION_USB_PERMISSION).apply {
                    this.putExtra(
                        "Path",
                        srcPath
                    )
                }
                val pendingIntent =
                    PendingIntent.getBroadcast(mApp, 0, intent, 0)
                usbManager.requestPermission(device.getUsbDevice(), pendingIntent)
                return null
            }
        }
        return result
    }

    @Synchronized
    private fun readDevice(
        device: UsbMassStorageDevice,
        srcPath: String,
        dstPath: String
    ): MutableList<Advertisement> {
        this.uiNotify.postValue(this.getNotify("AdsProgress"))
        Thread.sleep(100)
        var result = ArrayList<Advertisement>()
        device.init();
        val currentFs = device.getPartitions().get(0).getFileSystem()
        val root = currentFs.rootDirectory
        var files = root.listFiles()
        var file: UsbFile? = null
        while (file == null && files != null && files.size > 0) {
            for (item in files) {
                Log.d(AdvertisementViewModel.TAG, item.absolutePath)
                if (item.isDirectory() && srcPath.startsWith(item.absolutePath + "/", true)) {
                    if (srcPath == item.absolutePath + "/") file = item
                    else files = item.listFiles()
                    break;
                }
            }
        }
        if (file != null) {
            var list = readFolder(currentFs, file, dstPath);
            result.addAll(list)
        }
        return result
    }

    private fun readFolder(currentFs: FileSystem, file: UsbFile, targetDir: String)
            : MutableList<Advertisement> {
        var result = ArrayList<Advertisement>()
        for (item in file.listFiles()) {
            Log.d(AdvertisementViewModel.TAG, item.absolutePath + "--" + targetDir)
            if (item.isDirectory) {
                var dir = File("$targetDir${item.name}/")
                if (!dir.exists()) dir.mkdir()
                var list = readFolder(currentFs, item, dir.absolutePath)
                result.addAll(list)
                continue
            }
            var ad = Advertisement().apply { fileName = "$targetDir${item.name}" }
            result.add(ad)
            val source = UsbFileStreamFactory.createBufferedInputStream(item, currentFs);
            var targetFile = File(ad.fileName)
            if (targetFile.exists()) continue
            val target = FileOutputStream(targetFile)
            Log.d(AdvertisementViewModel.TAG, item.absolutePath + "--" + targetFile.absoluteFile)

            val buf = ByteArray(10 * 1024)
            var size = source.read(buf, 0, 10240)
            while (size > 0) {
                target.write(buf, 0, size)
                size = source.read(buf, 0, 10240)
            }
            source.close()
            target.close()
        }
        return result
    }
}
